﻿///////////////////////////////////////////////////////////////////////////////
// File:        Main.cc
// Author:      671643387@qq.com
// Description:
///////////////////////////////////////////////////////////////////////////////

#include <csignal>

#if defined(__WINDOWS__)
#include <crtdbg.h>
#endif

#include <boost/program_options.hpp>

#include "EchoServer.hpp"
namespace po = boost::program_options;

EchoServer* pServer = NULL;

void signal_handler(int signal)
{
    if (signal == SIGINT)
    {
        pServer->close();
    }
}

int main(int argc, char* argv[])
{
    {
        std::string addr;
        int port = 0;
        int backlog = 0;
        int threads = 0;
        bool useBuffSizeSet = false;
        unsigned int sndBufSize = 0;
        unsigned int rcvBufSize = 0;
        unsigned int isSize = 0;
        unsigned int osSize = 0;

        {
            po::options_description desc("Options");
            desc.add_options()
                ("help,h", "Help")
                ("address,a", po::value<std::string>()->default_value("0.0.0.0"), "Listen Address")
                ("port,p", po::value<int>()->default_value(8888), "Listen Port")
                ("backlog,b", po::value<int>()->default_value(5), "Backlog")
                ("threads,t", po::value<int>()->default_value(0), "Threads")
                ("bs,z", po::value<bool>()->default_value(false), "Use Socket Buffer Size Setting?")
                ("ss,s", po::value<unsigned int>()->default_value(0x1000), "Socket Send Buffer Size")
                ("rs,r", po::value<unsigned int>()->default_value(0x1000), "Socket Recv Buffer Size")
                ("is,i", po::value<unsigned int>()->default_value(0x1000), "InputStream Size")
                ("os,o", po::value<unsigned int>()->default_value(0x1000), "OutputStreamSize");

            po::variables_map vm;
            po::store(po::parse_command_line(argc, argv, desc), vm);

            if (vm.count("help"))
            {
                std::cout << desc << std::endl;
                return 0;
            }

            addr = vm["address"].as<std::string>();
            port = vm["port"].as<int>();
            backlog = vm["backlog"].as<int>();
            threads = vm["threads"].as<int>();
            useBuffSizeSet = vm["bs"].as<bool>();
            sndBufSize = vm["ss"].as<unsigned int>();
            rcvBufSize = vm["rs"].as<unsigned int>();
            isSize = vm["is"].as<unsigned int>();
            osSize = vm["os"].as<unsigned int>();
        }

#if defined(__WINDOWS__)
        WSADATA wsaData;
        WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif

        EchoServer server;
        pServer = &server;

        signal(SIGINT, signal_handler);

        assert(server.open(addr, port, backlog, threads
            , useBuffSizeSet, sndBufSize, rcvBufSize
            ,isSize, osSize));
        server.run();
    }

#if defined(__WINDOWS__)
    WSACleanup();
    _CrtDumpMemoryLeaks();
#endif
	return 0;
}